home *** CD-ROM | disk | FTP | other *** search
- *
- * 6569mono.i - Schnellere VIC-Emulation (Amiga monochrom)
- *
- * Copyright (C) 1994-1995 by Christian Bauer
- *
-
- *
- * Anmerkungen:
- * ------------
- *
- * Funktionsweise:
- * - Die monochrome Emulation arbeitet nicht mit einer Chunky-Bitmap,
- * sondern schreibt die rohen Grafikdaten direkt in eine Amiga-Bitplane
- * - Farbwerte werden ignoriert, der Hintergrund ist immer schwarz, die
- * Grafik immer weiß, ebenso bei den Sprites. Eine Ausnahme bildet die
- * Rahmenfarbe: Sie ist immer weiß, außer wenn der Rahmen schwarz ist
- *
-
-
- *
- * Definitionen
- *
-
- BytesPerLine = $180/8 ;Anzahl Bytes pro Zeile in einer Bitplane
-
- *
- * Makros
- *
-
- ; Sprite darstellen
- FDoSprite MACRO ;Nummer
- moveq #\1,d6 ;d6: Spritenummer
- btst d6,SPRITEON(a4) ;Wird das Sprite dargestellt?
- beq \@1$
-
- move.l MATRIXBASE(a4),a0
- moveq #0,d0
- move.b $03f8+\1(a0),d0 ;d0: Datenzeiger
- move.w MC\1(a4),d1 ;d1: MC
- move.w SPRX\1(a4),d5 ;d5: X-Koordinate
- bsr FDrawSprite
- \@1$
- ENDM
-
-
- **
- ** Eine Rasterzeile ausführen (monochrom)
- **
- ** d7: Rasterzeilenzähler
- ** a4: Zeiger auf VIC-Register
- ** a5: Zeiger auf das Ziel im Bildschirmspeicher
- **
-
- AmigaMono6569
-
- *
- * "Bad Lines"-Videomatrixzugriff:
- * 40 Bytes aus Videomatrix und Farb-RAM lesen und zwischenspeichern
- *
-
- tst.b BADLINEENABLE(a4) ;War das DEN-Bit in Rasterzeile $30 gesetzt?
- beq NoBadLine
-
- cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
- blo FNoBadLine
- cmp.w #LastDMALine,d7
- bhi FNoBadLine
-
- move.b d7,d0 ;Ja, stimmen die unteren Bits
- and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
- cmp.b YSCROLL+1(a4),d0 ;überein?
- bne FNoBadLine
-
- FIsBadLine st.b BADLINE(a4) ;Ja, Bad Line
- move.w VCCOUNT(a4),d2 ;d2: VC Videomatrix-Zähler
-
- move.l MATRIXBASE(a4),a0 ;Videomatrixbasis holen
- add.w d2,a0 ;Videomatrixzähler dazunehmen
-
- lea MatrixLine,a1 ;Nur Videomatrix-Zeile lesen
- movem.l (a0)+,d0-d6 ;40 Bytes kopieren
- movem.l d0-d6,(a1)
- movem.l (a0)+,d0-d2
- movem.l d0-d2,28(a1)
-
- clr.w RC(a4) ;RC zurücksetzen
- clr.b DISPLAYOFF(a4) ;Darstellung anschalten
-
- move.w BadLineCycles,CyclesLeft ;Andere Anzahl Zyklen
- FNoBadLine
-
- *
- * Oberen und unteren Rahmen handhaben
- *
-
- cmp.w DYSTOP(a4),d7 ;Unteres Ende des Fensters erreicht
- bne 1$ ; -> Rahmen einschalten
- st.b BORDERON(a4)
- bra FTBBorderDraw
-
- 1$ btst #4,CTRL1(a4) ;Rahmen nur abschalten, wenn DEN-Bit gesetzt
- beq FTBBorderDone
- cmp.w DYSTART(a4),d7 ;Oberes Ende des Fensters erreicht
- bne FTBBorderDone ; -> Rahmen abschalten
- clr.b BORDERON(a4)
- bra FTBNoBorder
-
- FTBBorderDone tst.b BORDERON(a4) ;Rahmen an?
- beq FTBNoBorder
-
- FTBBorderDraw move.l CURRENTA5(a4),a0 ;Ja, Rahmen malen
-
- tst.b $20(a4) ;Jede Farbe außer schwarz wird als weiß dargestellt
- beq FTBBorderBlack
-
- moveq #-1,d0 ;Rahmen weiß
- move.w #BytesPerLine/4-1,d1
- FTBBorderLoop move.l d0,(a0)+
- dbra d1,FTBBorderLoop
- bra FVICIncA5 ;Sonst nix
-
- FTBBorderBlack move.w #BytesPerLine/4-1,d1 ;Rahmen schwarz
- FTBBlackLoop clr.l (a0)+
- dbra d1,FTBBlackLoop
- bra FVICIncA5 ;Sonst nix
- FTBNoBorder
-
- *
- * Inhalt des Fensters: Darstellung eingeschaltet?
- *
-
- lea 4(a5),a1 ;a1: Ziel in Bildschirmspeicher
- lea MatrixLine,a2 ;a2: Zeichencodes
-
- tst.b DISPLAYOFF(a4) ;$3FFF darstellen?
- bne FShow3FFF
-
- move.l DisplayProc,a0 ;Nein, Routine entsprechend
- jmp (a0) ;dem Darstellungsmodus anspringen
-
- *
- * Standard-Text: Zeichendaten holen und darstellen
- *
-
- FTextStd add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
-
- move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
- add.w RC(a4),a0 ;RC dazunehmen
-
- clr.b 4(a5) ;Hintergrund, wenn XScroll>0
-
- moveq #0,d3 ;XScroll holen
- move.w XSCROLL(a4),d3
- beq FTextNoScroll
-
- ; Schleife für 40 Zeichen
- moveq #9,d1 ;d1: 4-Zeichen-Zähler
- moveq #0,d0
- FCharLoop move.b (a2)+,d0 ;Grafikdaten von 4 Zeichen lesen
- move.w (a0,d0.w*8),d2
- move.b (a2)+,d0
- move.b (a0,d0.w*8),d2
- swap d2
- move.b (a2)+,d0
- move.w (a0,d0.w*8),d2
- move.b (a2)+,d0
- move.b (a0,d0.w*8),d2
- bfins d2,(a1){d3:32} ;und in den Bildschirm schreiben
- addq.w #4,a1 ;Zielzeiger erhöhen
- dbra d1,FCharLoop
- bra FDoSprites
-
- ; Schleife für 40 Zeichen, kein XScroll
- FTextNoScroll moveq #9,d1 ;d1: 4-Zeichen-Zähler
- moveq #0,d0
- FNCharLoop move.b (a2)+,d0 ;Grafikdaten von 4 Zeichen lesen
- move.w (a0,d0.w*8),d2
- move.b (a2)+,d0
- move.b (a0,d0.w*8),d2
- swap d2
- move.b (a2)+,d0
- move.w (a0,d0.w*8),d2
- move.b (a2)+,d0
- move.b (a0,d0.w*8),d2
- move.l d2,(a1)+ ;und in den Bildschirm schreiben
- dbra d1,FNCharLoop
- bra FDoSprites
-
- *
- * Standard-BitMap: Grafikdaten holen und darstellen
- *
-
- FBitMapStd move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
- move.w VCCOUNT(a4),d0 ;VC holen
- lsl.w #3,d0 ;*8
- add.w RC(a4),d0 ;RC dazunehmen
- add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
-
- add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- clr.b 4(a5) ;Hintergrund, wenn XScroll>0
-
- moveq #0,d3 ;XScroll holen
- move.w XSCROLL(a4),d3
- beq FBitMapNoScroll
-
- ; Schleife für 40 Bytes
- moveq #9,d1 ;d1: 4-Zeichen-Zähler
- FBitMapLoop move.w (a0),d2 ;4 Bytes Grafikdaten lesen
- move.b 8(a0),d2
- swap d2
- move.w 16(a0),d2
- move.b 24(a0),d2
- bfins d2,(a1){d3:32} ;und in den Bildschirm schreiben
- addq.w #4,a1 ;Zielzeiger erhöhen
- lea 32(a0),a0 ;Quellzeiger erhöhen
- dbra d1,FBitMapLoop
- bra FDoSprites
-
- ; Schleife für 40 Bytes, kein XScroll
- FBitMapNoScroll moveq #9,d1 ;d1: 4-Zeichen-Zähler
- FNBitMapLoop move.w (a0),d2 ;4 Bytes Grafikdaten lesen
- move.b 8(a0),d2
- swap d2
- move.w 16(a0),d2
- move.b 24(a0),d2
- move.l d2,(a1)+ ;und in den Bildschirm schreiben
- lea 32(a0),a0 ;Quellzeiger erhöhen
- dbra d1,FNBitMapLoop
- bra FDoSprites
-
- *
- * Ungültiger Darstellungsmodus: Schwarzen Bildschirm anzeigen
- *
-
- FBlackScreen add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- moveq #9,d0 ;40 Zeichen schwarz
- 1$ clr.l (a1)+
- dbra d0,1$
- bra FDoSprites
-
- *
- * $3FFF darstellen
- *
-
- FShow3FFF tst.b $21(a4) ;Wenn der Hintergrund schwarz ist, sieht man nichts
- beq FInvis3FFF
-
- moveq #0,d3 ;XScroll holen
- move.w XSCROLL(a4),d3
-
- clr.b 4(a5) ;Hintergrund, wenn X-Scroll>0
-
- btst #6,CTRL1(a4)
- bne 11$
- move.w #$3fff,d0 ;Byte bei $3FFF lesen
- bra 12$
- 11$ move.w #$39ff,d0 ;ECM: Byte bei $39FF lesen
- 12$ bsr GetPhysical
-
- move.w (a0),d0 ;Byte als Langwort lesen
- move.b (a0),d0
- swap d0
- move.w (a0),d0
- move.b (a0),d0
- not.l d0 ;und invertieren
-
- ; Zeile schreiben
- moveq #9,d1 ;d0: 4-Zeichen-Zähler
- FLoop3FFF bfins d0,(a1){d3:32} ;In den Bildschirm schreiben
- addq.w #4,a1 ;Zielzeiger erhöhen
- dbra d1,FLoop3FFF
- bra FDoSprites
-
- ; Hintergrund schwarz: 3FFF unsichtbar
- FInvis3FFF moveq #9,d1 ;d0: 4-Zeichen-Zähler
- FLoop3FFFInvis clr.l (a1)+ ;In den Bildschirm schreiben
- dbra d1,FLoop3FFFInvis
-
- *
- * Sprites
- *
-
- FDoSprites tst.b SPRITEON(a4) ;Ist überhaupt ein Sprite z.Z. sichtbar?
- bne FDrawTheSprites ;Ja, dann Sprites malen
-
- *
- * Linken und rechten Rahmen zeichnen
- *
-
- ; 40-Spalten-Rahmen
- FDrawLRBorder move.l CURRENTA5(a4),a0
-
- tst.b $20(a4)
- beq FLRBorderBlack
-
- moveq #-1,d0
- move.l d0,(a0) ;Links: $00..$17
- move.l d0,44(a0) ;Rechts: $158..$16f
-
- ; 38-Spalten-Rahmen
- tst.b IS38COL(a4)
- beq 1$
- move.b d0,4(a0) ;Links: $18..$1e
- move.b d0,43(a0) ;Rechts: $14f..$157
- 1$ bra FVICNext
-
- ; Schwarzer Rahmen
- FLRBorderBlack clr.l (a0) ;40-Spalten
- clr.l 44(a0)
- tst.b IS38COL(a4) ;38-Spalten
- beq 1$
- clr.b 4(a0)
- clr.b 43(a0)
- 1$
-
- *
- * Ende einer sichtbaren Zeile: Zeiger in Bitmap erhöhen
- *
-
- FVICNext
- FVICIncA5 lea BytesPerLine(a5),a5
- move.l a5,CURRENTA5(a4)
-
- *
- * Zurück zur Haupt-Routine
- *
-
- bra VICIncRC
-
- *
- * Mindestens ein Sprite ist sichtbar, Sprites malen
- *
-
- ; Sprites malen
- FDrawTheSprites move.l d7,-(sp)
- FDoSprite 7
- FDoSprite 6
- FDoSprite 5
- FDoSprite 4
- FDoSprite 3
- FDoSprite 2
- FDoSprite 1
- FDoSprite 0
- move.l (sp)+,d7
- bra FDrawLRBorder
-
-
- **
- ** Ein Sprite zeichnen (monochrom)
- ** d0.l: Spritedatenzeiger
- ** d1.w: MC
- ** d5.w: X-Koordinate
- ** d6.l: Spritenummer (0..7)
- **
-
- CNOP 0,4
- FDrawSprite lsl.w #6,d0 ;Datenzeiger*64
- add.w d1,d0 ;MC dazunehmen
- bsr GetPhysical ;a0: Spritedaten
-
- move.w d5,d0 ;X-Koordinate
- lsr.w #3,d0 ;Pixel in Bytes umrechnen
- lea 1(a5,d0.w),a1 ;a1: Ziel im Bildschirmspeicher
-
- btst d6,MXE(a4) ;X-expandiert?
- bne FSprExp
-
- cmp.w #$180-24,d5 ;Sprite horizontal sichtbar?
- bhs FSpriteDone
-
- ; Standard-Sprite
- and.w #7,d5 ;d5: Bit-Shift
-
- move.l (a0),d0 ;Sprite-Daten lesen,
- clr.b d0 ; auf 24 Bit beschränken
- lsr.l d5,d0 ; verschieben
- or.l d0,(a1) ; und in den Bildschirm schreiben
- FSpriteDone rts
-
- ; X-expandiertes Sprite
- FSprExp cmp.w #$180-48,d5 ;Sprite horizontal sichtbar?
- bhs FSpriteDone
-
- move.l (a0),d0 ;Sprite-Daten lesen
- lea ExpTable,a0 ; und expandieren (3 Bytes -> 3 Worte)
- moveq #0,d1
- rol.l #8,d0
- move.b d0,d1
- move.w (a0,d1.w*2),d2
- swap d2
- rol.l #8,d0
- move.b d0,d1
- move.w (a0,d1.w*2),d2
- moveq #0,d3
- rol.l #8,d0
- move.b d0,d1
- move.w (a0,d1.w*2),d3
- swap d3
-
- and.w #7,d5 ;d5: Bit-Shift
- bne 1$
- or.l d2,(a1)+ ;Kein Shift, in den Bildschirm schreiben
- or.l d3,(a1)
- rts
-
- 1$ subq.w #1,d5 ;Daten verschieben
- 2$ lsr.l #1,d2
- roxr.l #1,d3
- dbra d5,2$
-
- or.l d2,(a1)+ ;und in den Bildschirm schreiben
- or.l d3,(a1)
- rts
-
- *
- * Tabelle zum X-expandieren von Sprites
- *
-
- CNOP 0,4
- ExpTable INCBIN "ExpTable.bin"
-